﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;

namespace Notepad_Clone.FindReplace
{
    public enum Direction
    {
        Up,
        Down
    }

    class FindReplaceDialog : Window
    {
        protected Label lblReplace;
        protected TextBox txtboxFind, txtboxReplace;
        protected CheckBox checkMatch;
        protected GroupBox groupDirection;
        protected RadioButton radioDown, radioUp;
        protected Button btnFind, btnReplace, btnAll;

        #region 自定义事件
        public event EventHandler FindNext;
        public event EventHandler Replace;
        public event EventHandler ReplaceAll;

        protected virtual void OnFindNext(EventArgs args)
        {
            if (this.FindNext != null)
            {
                this.FindNext(this, args);
            }
        }

        protected virtual void OnReplace(EventArgs args)
        {
            if (this.Replace != null)
            {
                this.Replace(this, args);
            }
        }

        protected virtual void OnReplaceAll(EventArgs args)
        {
            if (this.ReplaceAll != null)
            {
                this.ReplaceAll(this, args);
            }
        }
        #endregion

        public string FindWhat
        {
            set
            {
                this.txtboxFind.Text = value;
            }

            get
            {
                return this.txtboxFind.Text;
            }
        }

        public string ReplaceWith
        {
            set
            {
                this.txtboxReplace.Text = value;
            }

            get
            {
                return this.txtboxReplace.Text;
            }
        }

        public bool MatchCase
        {
            set
            {
                this.checkMatch.IsChecked = value;
            }

            get
            {
                return this.checkMatch.IsChecked.GetValueOrDefault();
            }
        }

        public Direction Direction
        {
            set
            {
                if (value == Direction.Down)
                {
                    this.radioDown.IsChecked = true;
                }
                else
                {
                    this.radioUp.IsChecked = true;
                }
            }

            get
            {
                return this.radioDown.IsChecked.GetValueOrDefault() ? Direction.Down : Direction.Up;
            }
        }

        protected FindReplaceDialog(Window owner)
        {
            this.ShowInTaskbar = false;
            this.WindowStyle = WindowStyle.ToolWindow;
            this.SizeToContent = SizeToContent.WidthAndHeight;
            this.WindowStartupLocation = WindowStartupLocation.CenterOwner;
            this.Owner = owner;

            Grid grid = new Grid();
            this.Content = grid;

            for (int i = 0; i < 3; i++)
            {
                RowDefinition rowdef = new RowDefinition();
                rowdef.Height = GridLength.Auto;
                grid.RowDefinitions.Add(rowdef);

                ColumnDefinition coldef = new ColumnDefinition();
                coldef.Width = GridLength.Auto;
                grid.ColumnDefinitions.Add(coldef);
            }

            Label lbl = new Label();
            lbl.Content = "Fi_nd what:";
            lbl.VerticalAlignment = VerticalAlignment.Center;
            lbl.Margin = new Thickness(12);
            grid.Children.Add(lbl);
            Grid.SetRow(lbl, 0);
            Grid.SetColumn(lbl, 0);

            this.txtboxFind = new TextBox();
            this.txtboxFind.Margin = new Thickness(12);
            this.txtboxFind.TextChanged += this.FindTextBoxOnTextChanged;
            grid.Children.Add(this.txtboxFind);
            Grid.SetRow(this.txtboxFind, 0);
            Grid.SetColumn(this.txtboxFind, 1);

            this.lblReplace = new Label()
            {
                Content = "Re_place with:",
                VerticalAlignment = VerticalAlignment.Center,
                Margin = new Thickness(12)
            };
            grid.Children.Add(this.lblReplace);
            Grid.SetRow(this.lblReplace, 1);
            Grid.SetColumn(this.lblReplace, 0);

            this.txtboxReplace = new TextBox()
            {
                Margin = new Thickness(12)
            };
            grid.Children.Add(this.txtboxReplace);
            Grid.SetRow(this.txtboxReplace, 1);
            Grid.SetColumn(this.txtboxReplace, 1);

            this.checkMatch = new CheckBox()
            {
                Content = "Match _case",
                VerticalAlignment = VerticalAlignment.Center,
                Margin = new Thickness(12)
            };
            grid.Children.Add(this.checkMatch);
            Grid.SetRow(this.checkMatch, 2);
            Grid.SetColumn(this.checkMatch, 0);

            this.groupDirection = new GroupBox()
            {
                Header = "Direction",
                Margin = new Thickness(12),
                HorizontalAlignment = HorizontalAlignment.Left
            };
            grid.Children.Add(this.groupDirection);
            Grid.SetRow(this.groupDirection, 2);
            Grid.SetColumn(this.groupDirection, 1);

            StackPanel stack = new StackPanel();
            stack.Orientation = Orientation.Horizontal;
            groupDirection.Content = stack;

            this.radioUp = new RadioButton()
            {
                Content = "_Up",
                Margin = new Thickness(6)
            };
            stack.Children.Add(this.radioUp);

            this.radioDown = new RadioButton()
            {
                Content = "_Down",
                Margin = new Thickness(6)
            };
            stack.Children.Add(this.radioDown);

            stack = new StackPanel()
            {
                Margin = new Thickness(6)
            };
            grid.Children.Add(stack);
            Grid.SetRow(stack, 0);
            Grid.SetColumn(stack, 2);
            Grid.SetRowSpan(stack, 3);

            this.btnFind = new Button()
            {
                Content = "_Find Next",
                Margin = new Thickness(6),
                IsDefault = true
            };
            this.btnFind.Click += this.FindeNextOnClick;
            stack.Children.Add(this.btnFind);

            this.btnReplace = new Button()
            {
                Content = "_Replace",
                Margin = new Thickness(6)
            };
            this.btnReplace.Click += this.ReplaceOnClick;
            stack.Children.Add(this.btnReplace);

            this.btnAll = new Button()
            {
                Content = "Replace _All",
                Margin = new Thickness(6)
            };
            this.btnAll.Click += this.ReplaceAllOnClick;
            stack.Children.Add(this.btnAll);

            Button btn = new Button()
            {
                Content = "Cancel",
                Margin = new Thickness(6),
                IsCancel = true
            };
            btn.Click += this.CancelOnClick;
            stack.Children.Add(btn);

            this.txtboxFind.Focus();
        }

        #region 事件处理
        void FindTextBoxOnTextChanged(object sender, TextChangedEventArgs args)
        {
            TextBox txtbox = args.Source as TextBox;
            this.btnFind.IsEnabled = this.btnReplace.IsEnabled = this.btnAll.IsEnabled = (txtbox.Text.Length > 0);
        }

        void FindeNextOnClick(object sender, RoutedEventArgs args)
        {
            this.OnFindNext(new EventArgs());
        }

        void ReplaceOnClick(object sender, RoutedEventArgs args)
        {
            this.OnReplace(new EventArgs());
        }

        void ReplaceAllOnClick(object sender, RoutedEventArgs args)
        {
            this.OnReplaceAll(new EventArgs());
        }

        void CancelOnClick(object sender, RoutedEventArgs args)
        {
            this.Close();
        }
        #endregion
    }
}
